/**
 * WhiMAIcpp - C++ interface for the Whiskey Media APIs.
 *  Copyright (C) 2010  Anders Bugge
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "detail.h"

// STL includes
#ifdef WHIMAI_DEBUG
#include <iostream>
#endif

// VMA includes
#include "apikeys.h"

namespace WM
{

const std::string URL_ID_SPLIT = "/";
const std::string URL_APIKEY = "/?api_key=";
const std::string URL_FORMAT = "&format=json";

DetailBase::DetailBase( std::string name, std::string site, std::string key ) : Parser()
{
	type = name;
	URL_START = site;
	apikey = key;
	URL_EXTRA = "";
}

DetailBase::DetailBase( std::string name, std::string site, std::string key, unsigned int id, bool* ok ) : Parser()
{
	type = name;
	URL_START = site;
	apikey = key;
	URL_EXTRA = "";
	update( id, ok );
}

DetailBase::~DetailBase()
{
	for( std::map<std::string, Array*>::iterator it = arrays.begin(); it != arrays.end(); it++ )
		delete it->second;
}

void DetailBase::update( unsigned int id, bool* ok )
{
	// update request url
	std::stringstream ss;
	ss << URL_START << type << URL_ID_SPLIT << id << URL_APIKEY << apikey << URL_EXTRA << URL_FORMAT;
	url = ss.str();

	// get the data
	bool okay = parseData();
	if( ok )
		*ok = okay;
}

double DetailBase::asValue( std::string item, bool* ok )
{
	bool okay = false;
	try
	{
		int pos = item.find(',');
		std::string item2 = "";
		if( pos != std::string::npos )
		{
			char buf[100] = {'\0'};
			item.copy( buf, item.size()-pos-1, pos+1);
			item2 += buf;
			char buf2[100] = {'\0'};
			item.copy( buf2, pos, 0);
			item = buf2;
		}

		const json::UnknownElement& uElm = getElement( item, &okay );
		if( ok )
			*ok = false;

		if( okay )
		{
			if( item2.empty() )
				return ((json::Number)uElm).Value();
			else
				return ((json::Number)(uElm[item2])).Value();
		}
	}
	catch( const json::Exception& e)
	{
#ifdef WHIMAI_DEBUG
		std::cout << "JSON ERROR: " << e.what() << std::endl;
#endif
	}
	return 0.0;
}

std::string DetailBase::asString( std::string item, bool* ok )
{
	bool okay = false;
	try
	{
		int pos = item.find(',');
		std::string item2 = "";
		if( pos != std::string::npos )
		{
			char buf[100] = {'\0'};
			item.copy( buf, item.size()-pos-1, pos+1);
			item2 += buf;
			memset(buf, 0, 100);
			item.copy( buf, pos, 0);
			item = buf;
		}

		const json::UnknownElement& uElm = getElement( item, &okay );
		if( ok )
			*ok = okay;

		if( okay )
		{
			if( item2.empty() )
				return ((json::String)uElm).Value();
			else
				return ((json::String)(uElm[item2])).Value();
		}
	}
	catch( const json::Exception& e)
	{
#ifdef WHIMAI_DEBUG
		std::cout << "JSON ERROR: " << e.what() << std::endl;
#endif
	}

	return "";
}

Array* DetailBase::asArray( std::string item, bool* ok )
{
	if( arrays.find(item) != arrays.end() )
		return arrays[item];

	bool okay = false;
	try
	{
		const json::UnknownElement& uElm = getElement( item, &okay );
		if( ok )
			*ok = okay;

		if( okay )
		{
			arrays[item] = new Array( ((const json::Array&)uElm) );
			return arrays[item];
		}
	}
	catch( const json::Exception& e)
	{
#ifdef WHIMAI_DEBUG
		std::cout << "JSON ERROR: " << e.what() << std::endl;
#endif
	}

	return NULL;
}

const json::UnknownElement& DetailBase::getElement( std::string item, bool* ok )
{
	try
	{
		const json::UnknownElement& uElm = jObject->Find("results")->element[item];
		*ok = true;
		return uElm;
	}
	catch( const json::Exception& e)
	{
#ifdef WHIMAI_DEBUG
		std::cout << "JSON ERROR: " << e.what() << std::endl;
#endif
		*ok = false;
	}

	const json::UnknownElement& uElm = json::UnknownElement();
	return uElm;
}

namespace GB
{

Detail::Detail( std::string name ) : DetailBase( name, "http://api.giantbomb.com/", APIKEY )
{

}

Detail::Detail( std::string name, unsigned int id, bool* ok ) : DetailBase( name, "http://api.giantbomb.com/", APIKEY, id, ok )
{

}

}

namespace CV
{

Detail::Detail( std::string name ) : DetailBase( name, "http://api.comicvine.com/", APIKEY )
{

}

Detail::Detail( std::string name, unsigned int id, bool* ok ) : DetailBase( name, "http://api.comicvine.com/", APIKEY, id, ok )
{

}

}

}
